﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

using OpenCvSharp;
using OpenCvSharp.XImgProc;
using System.IO;
using OpenCvSharp.Extensions;
using System.Diagnostics;

namespace OCRDemo
{
    public partial class FormOcr : Form
    {
        public FormOcr()
        {
            InitializeComponent();
        }
        [DllImport("paddlex_ocr.dll", EntryPoint = "LoadModel", SetLastError = true, CharSet = CharSet.Ansi)]
        static extern bool LoadModel(ref IntPtr pdet, ref IntPtr pcls, ref IntPtr prec);

        [DllImport("paddlex_ocr.dll", EntryPoint = "Rec", SetLastError = true, CharSet = CharSet.Ansi)]
        static extern void Rec(IntPtr pdet, IntPtr pcls, IntPtr prec, IntPtr input, int height, int width, out string result);
        string image_path = "D:/ocr/Release/Release/11.jpg";
        private void button1_Click(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Now;
            try
            {
                OpenFileDialog fileDialog = new OpenFileDialog();
                if (fileDialog.ShowDialog() == DialogResult.OK)
                {
                    image_path = fileDialog.FileName;
                    if (File.Exists(image_path))
                    {
                        //Bitmap bmp = (Bitmap)Image.FromFile(ImgPath);
                        Mat mat = Cv2.ImRead(image_path);
                        //Bitmap bmp = mat.ToBitmap();
                        //Bitmap bmp2 = Inference3(mat);
                        pictureBox1.Image = mat.ToBitmap();
                        string result = "";
                        dt = DateTime.Now;
                        Rec(pdet, pcls, prec, mat.Data, mat.Width, mat.Height, out result);  //out seg_img
                        richTextBox1.Text = result;
                        if (string.IsNullOrEmpty(result) == false)
                            Console.WriteLine(result);
                        else
                            Console.WriteLine("NULL");
                        OcrJson ocr = JsonHelper.DeserializeJsonToObject<OcrJson>(result);
                        //Mat img = mat;
                        if (ocr != null && ocr.array != null)
                        {
                            JsonHelper.SetFormat(true);
                            richTextBox1.Text = JsonHelper.SerializeObject(ocr);
                            string str = "";

                            foreach (var item in ocr.array)
                            {
                                Rect rect = new Rect(item.box.left, item.box.top, item.box.width, item.box.height);
                                Cv2.Rectangle(mat, rect, new Scalar(0, 255, 0), 2);
                                str += item.str + "\r\n";
                            }
                            richTextBox2.Text = str;
                        }
                        Console.WriteLine($"耗时：{DateTime.Now.Subtract(dt).TotalMilliseconds}ms");
                        label1.Text = $"耗时：{DateTime.Now.Subtract(dt).TotalMilliseconds}ms";
                        //Bitmap seg_show = new Bitmap(img.Cols, img.Rows, (int)img.Step(), System.Drawing.Imaging.PixelFormat.Format24bppRgb, img.Data);
                        pictureBox2.Image?.Dispose();
                        pictureBox2.Image = mat.ToBitmap();
                        mat.Dispose();
                        GC.Collect();

                    }
                }
            }
            catch (Exception ex)
            {
                ;
            }
        }
        // 将Btimap类转换为byte[]类函数
        public static byte[] GetBGRValues(Bitmap bmp, out int stride)
        {
            var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
            var bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
            stride = bmpData.Stride;
            var rowBytes = bmpData.Width * Image.GetPixelFormatSize(bmp.PixelFormat) / 8;
            var imgBytes = bmp.Height * rowBytes;
            byte[] rgbValues = new byte[imgBytes];
            IntPtr ptr = bmpData.Scan0;
            for (var i = 0; i < bmp.Height; i++)
            {
                Marshal.Copy(ptr, rgbValues, i * rowBytes, rowBytes);
                ptr += bmpData.Stride;
            }
            bmp.UnlockBits(bmpData);
            return rgbValues;
        }

        IntPtr pdet = IntPtr.Zero;
        IntPtr pcls = IntPtr.Zero;
        IntPtr prec = IntPtr.Zero;
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                bool ok = LoadModel(ref pdet, ref pcls, ref prec);
                if (ok)
                {
                    Console.WriteLine("ok");
                }
                else
                {
                    Console.WriteLine("not ok");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        bool runtest = false;
        private void button3_Click(object sender, EventArgs e)
        {
            runtest = !runtest;
            if (runtest)
                Task.Run(() =>
                {
                    while (runtest)
                    {
                        if (File.Exists(image_path))
                        {
                            using (Mat mat = Cv2.ImRead(image_path))
                            {
                                string result = "";
                                Rec(pdet, pcls, prec, mat.Data, mat.Width, mat.Height, out result);  //out seg_img
                                if (string.IsNullOrEmpty(result) == false)
                                    Console.WriteLine(result);
                                else
                                    Console.WriteLine("NULL");
                                OcrJson ocr = JsonHelper.DeserializeJsonToObject<OcrJson>(result);
                            }
                            GC.Collect();
                            Console.WriteLine("======================once over=======================");
                        }
                        else
                        {
                            runtest = false;
                            Console.WriteLine("未选择文件");
                        }
                    }
                    Console.WriteLine("=================test over=================");
                });
        }

        private void pictureBox2_Click(object sender, EventArgs e)
        {
            if (pictureBox2.Image == null) return;
            FormShow frm = new FormShow();
            frm.Show(pictureBox2.Image);
            frm.Show(this);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            FormStr form = new FormStr();
            form.Show(this);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            pictureBox1.Image = null;
            pictureBox2.Image = null;
            richTextBox1.Clear();
            richTextBox2.Clear();
            label1.Text = "";
        }

        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                OcrJson ocr = JsonHelper.DeserializeJsonToObject<OcrJson>(richTextBox1.Text);
                if (ocr != null && ocr.array != null)
                {
                    JsonHelper.SetFormat(true);
                    richTextBox1.Text = JsonHelper.SerializeObject(ocr);
                    string str = "";

                    foreach (var item in ocr.array)
                    {
                        //Rect rect = new Rect(item.box.left, item.box.top, item.box.width, item.box.height);
                        //Cv2.Rectangle(img, rect, new Scalar(0, 255, 0), 2);
                        str += item.str + "\r\n";
                    }
                    richTextBox2.Text = str;
                }
            }
            catch (Exception)
            {

                throw;
            }
        }
    }
}